package com.ljl.service;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ljl.domain.NodeData;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 刘家良
 * @date 2022/10/26 23:16
 * @description
 */
public class NodeDataService {

    /** 一次性最大传输的数据量 */
    private final int transportSize = 5;
    private final List<NodeData> dataTruck = new ArrayList<>();
    private final List<NodeData> tempTruck = new ArrayList<>();
    private final String backendUrl;

    public NodeDataService(String backendUrl) {
        this.backendUrl = backendUrl;
        ThreadUtil.execute(() -> {
            while (true) {
                //上传数据
                uploadData();
                //休眠5秒
                ThreadUtil.sleep(5, TimeUnit.SECONDS);
            }
        });
    }

    /**
     * 将数据保存到集合truck内，以备发送
     * @param data 节点数据
     */
    public void recordData(NodeData data) {
        //如果数据量已超过一次性传输的限制，将放进缓存集合内
        if (dataTruck.size() < transportSize) {
            dataTruck.add(data);
        }else {
            tempTruck.add(data);
        }
    }

    /**
     * 上传节点数据
     */
    private synchronized void uploadData() {
        //获取数据
        JSONArray jsonArray = JSONArray.parseArray(JSONObject.toJSONString(dataTruck));
        //清空数据
        dataTruck.clear();
        //将缓存中的数据放进dataTruck准备下一次上传数据
        for (int i = 0; i < tempTruck.size(); i++) {
            if (i < transportSize) {
                dataTruck.add(tempTruck.get(i));
            }else {
                break;
            }
        }
        //如果下一次上传的数据量小于最大的上传限制量，则说明缓存中的数据没有装满，所以需要清空缓存中的数据
        if (dataTruck.size() < transportSize) {
            tempTruck.clear();
        }
        //如果下一次需要上传的数据等于最大上传限制量，说明缓存中的数据可能还有多的，那么就需要从缓存中清除已添加到下轮的数据
        if (dataTruck.size() == transportSize) {
            for (int i = transportSize - 1; i >= 0; i--) {
                tempTruck.remove(i);
            }
        }
        System.out.printf("向[%s]上传数据[%s]\r\n", backendUrl, jsonArray);
        try{
            HttpRequest body = HttpUtil.createPost(backendUrl).body(jsonArray.toJSONString());
            body.execute();
        }catch (Exception e) {
            System.err.println("数据上传失败!请先开启后端程序");
        }
    }

}
